ActivityGroup简介
ActivityGroup
可以看作是Activity
的容器,可以包含多个嵌套进来的Activity
。
我们只需要知道有这个类就可以了,现在这个类现在已经不推荐使用了,是deprecated
状态的,一般情况下是可以被Fragment
取代的,但是在一些特殊场合下仍然是被需要的。
下面通过一个Demo来介绍ActivityGroup
的使用。
示例
代码
MainActivity.java1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36public class MainActivity extends ActivityGroup {
private ViewGroup mLeft;
private ViewGroup mRight;
private LocalActivityManager manager;
private View mRoot;
private static WeakReference<MainActivity> mInstance;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mInstance = new WeakReference<MainActivity>(this);
setContentView(R.layout.activity_main);
manager = getLocalActivityManager();
mRoot = findViewById(R.id.container_main);
mLeft = (ViewGroup) findViewById(R.id.container_left);
mRight = (ViewGroup) findViewById(R.id.container_right);
startLeftActivity();
}
public static MainActivity getInstance(){
return mInstance != null ? mInstance.get() : null;
}
public void startLeftActivity(){
mLeft.removeAllViews();
Intent i = new Intent(this, LeftActivity.class);
mLeft.addView(manager.startActivity("LeftActivity", i).getDecorView());
}
public void startRightActivity(){
mRight.removeAllViews();
Intent i = new Intent(this, RightActivity.class);
mRight.addView(manager.startActivity("RightActivity", i).getDecorView());
}
}
activity_main.xml1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<LinearLayout
android:id="@+id/container_main"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
android:showDividers="middle"
android:divider="?android:attr/dividerHorizontal"
tools:context="com.android.hq.testapplication.MainActivity">
<FrameLayout
android:id="@+id/container_left"
android:layout_width="150dp"
android:layout_height="match_parent"
android:layout_weight="0">
</FrameLayout>
<FrameLayout
android:id="@+id/container_right"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Empty"/>
</FrameLayout>
</LinearLayout>
LeftActivity.java1
2
3
4
5
6
7
8
9
10
11public class LeftActivity extends Activity{
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_left);
}
public void startRightActivity(View v){
MainActivity.getInstance().startRightActivity();
}
}
效果
在启动右边的Activity
之前,右边区域是空的:
点击按钮启动右边Activity
:
源码分析
从源码中我们可以看到ActivityGroup
类的父类是Activity
,也就是说二者具有相同的方法和生命周期。在ActivityGroup
有成员变量protected LocalActivityManager mLocalActivityManager
,那么ActivityGroup
对Activity
的管理就要以来这个变量来管理了。
在ActivityGroup
的onCreate`
onResumeonPause`等生命周期函数里面分别调用
1
2
3Bundle states = savedInstanceState != null
? (Bundle) savedInstanceState.getBundle(STATES_KEY) : null;
mLocalActivityManager.dispatchCreate(states);
1 | mLocalActivityManager.dispatchResume(); |
1 | mLocalActivityManager.dispatchPause(isFinishing()); |
来保证子Activity
的生命周期与ActivityGroup
一致。LocalActivityManager
通过startActivity(String id,Intent intent)
这个方法获取当前Window
对象,再然后调用getDecorView()
方法获取当前Activity
对应的View
,这个就把多个Activity
添加到一个RootView
里面了。
具体是怎么获得我们需要Activity
的DecorView
的呢?我们就要看一下LocalActivityManager
的startActivity
这个方法了。
首先要获取主线程的mActivityThread
:1
mActivityThread = ActivityThread.currentActivityThread();
1 | r.activity = mActivityThread.startActivityNow( |
这里调用了mActivityThread.startActivityNow
方法,在startActivityNow
内部会调用ActivityThread.performLaunchActivity
来装载这个Activity
,然后通过activity.getWindow()
获得Window
对象,在通过Window
获得DecorView
。